package org.dreamfly.core.service.impl;

import org.dreamfly.core.action.FileActionSupport;
import org.dreamfly.core.bean.SzTempVideo;
import org.dreamfly.core.bean.SzVideo;
import org.dreamfly.core.bean.SzVideoType;
import org.dreamfly.core.dao.TempVideoDAO;
import org.dreamfly.core.dao.VideoDAO;
import org.dreamfly.core.dao.VideoTypeDAO;
import org.dreamfly.core.page.PageInfo;
import org.dreamfly.core.page.PageResultSet;
import org.dreamfly.core.service.VideoService;
import org.dreamfly.core.util.CharacterJudger;
import org.dreamfly.core.util.ContentDll;
import org.dreamfly.core.util.ContentDll.VideoInfo;
import org.dreamfly.core.util.UrlGetter;
import org.dreamfly.core.util.creatVideoFile;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class VideoServiceImpl implements VideoService {
    private VideoDAO videoDAO;
    private VideoTypeDAO videoTypeDAO;
    private TempVideoDAO tempVideoDAO;
    private creatVideoFile creatVideoFile = new creatVideoFile();
    private String ip;
    private String name;
    private String username;
    private String password;
    private String tableName;
    private String applicationPath;
    private String serverName;
    private UrlGetter urlGetter;
    private Lock videoLock =  new ReentrantLock();

    @Override
    public void deleteVideo(Long id) {
        SzVideo v = videoDAO.find(SzVideo.class, id);
        String name = v.getVideoUrl().substring(v.getVideoUrl().lastIndexOf("/") + 1, v.getVideoUrl().length());
        videoLock.lock();
        System.out.println(ContentDll.INSTANCE.OpenDatabase(ip, this.name, username, password, tableName));
        System.out.println(name);
        System.out.println(ContentDll.INSTANCE.Delete_data(name, CharacterJudger.isUTF_8()));
        FileActionSupport fas = new FileActionSupport();
        String[] filePaths = {v.getVideoUrl(), v.getMinPictureUrl()};
        fas.setFilePaths(filePaths);
        try {
            videoDAO.delete(v);
            fas.delete();

        } catch (Exception e) {
            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
        } finally {
            ContentDll.INSTANCE.ColseDatabase();
            videoLock.unlock();
        }
    }


    @Override
    public List<SzVideo> normalSearchByType(SzVideo video,
                                            List<SzVideoType> videoTypes) {

        return null;
    }

    @Override
    public void saveOrUpdate(SzVideo video) {
        videoDAO.saveOrUpdate(video);
    }

    @Override
    public PageResultSet<SzVideo> normalSearch(SzVideo video, Long pageSize, Long page, String serverName) {
        PageInfo pageInfo = null;
        List<SzVideo> list = null;
        if (serverName == null) {
            pageInfo = new PageInfo(videoDAO.findCount(SzVideo.class, video.getTitle()), pageSize, page);
            list = videoDAO.find(SzVideo.class,
                    video.getTitle(),
                    Integer.parseInt(pageInfo.getBeginIndex().toString()),
                    Integer.parseInt(pageInfo.getPageSize().toString()), null);
        } else {
            pageInfo = new PageInfo(videoDAO.findNativeCount(SzVideo.class, video.getTitle(), serverName), pageSize, page);
            list = videoDAO.findNative(SzVideo.class,
                    video.getTitle(),
                    serverName,
                    Integer.parseInt(pageInfo.getBeginIndex().toString()),
                    Integer.parseInt(pageInfo.getPageSize().toString()));
        }
        PageResultSet<SzVideo> pageResultSet = new PageResultSet<SzVideo>();
        pageResultSet.setList(list);
        pageResultSet.setPageInfo(pageInfo);
        return pageResultSet;
    }

    @Override
    public PageResultSet<SzVideo> normalSearchByType(SzVideo video, List<Long> szVideoTypeIds, Long pageSize, Long page, String serverName) {
        PageInfo pageInfo = null;
        List<SzVideo> list = null;
        if (null == szVideoTypeIds) {
            szVideoTypeIds = new ArrayList<Long>();
            List<SzVideoType> types = videoTypeDAO.findAll(SzVideoType.class);
            for (SzVideoType type : types) {
                szVideoTypeIds.add(type.getTypeId());
            }
        }
        if (null == serverName) {
            pageInfo = new PageInfo(videoDAO.findCount(szVideoTypeIds, video.getTitle(), null), pageSize, page);
            list = videoDAO.findByType(szVideoTypeIds,
                    video.getTitle(),
                    Integer.parseInt(pageInfo.getBeginIndex().toString()),
                    Integer.parseInt(pageInfo.getPageSize().toString()), null);
        } else {
            pageInfo = new PageInfo(videoDAO.findCount(szVideoTypeIds, video.getTitle(), serverName), pageSize, page);
            list = videoDAO.findByType(szVideoTypeIds,
                    video.getTitle(),
                    Integer.parseInt(pageInfo.getBeginIndex().toString()),
                    Integer.parseInt(pageInfo.getPageSize().toString()), serverName);
        }
        if (null != list) {
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                SzVideo temp = (SzVideo) iterator.next();
                temp.setMinPictureUrl(urlGetter.getRemoteUrl(temp.getMinPictureUrl(), temp.getServer()));
            }
        }
        PageResultSet<SzVideo> pageResultSet = new PageResultSet<SzVideo>();
        pageResultSet.setList(list);
        pageResultSet.setPageInfo(pageInfo);
        return pageResultSet;
    }

    @Override
    public SzVideo findDetail(Long id) {

        SzVideo video = videoDAO.find(SzVideo.class, id);
        video.setMinPictureUrl(urlGetter.getRemoteUrl(video.getMinPictureUrl(),video.getServer()));
        return video;
    }

    @Override
    public void addVideoInfo(SzVideo video) {
        videoDAO.saveInfo(video);
    }


    @Override
    public void changeType(Long videoId, Long videoTypeId, String disrate) {
        SzVideoType type = videoTypeDAO.find(SzVideoType.class, videoTypeId);
        videoDAO.changeType(videoId, type, disrate);
    }

    @Override
    public List<SzTempVideo> contentSearch(String relativeVideoDir, Long pageSize,
                                           Long page) {
        String videoDir = applicationPath + relativeVideoDir;
        ContentDll.INSTANCE.OpenDatabase(ip, name, username, password, tableName);
        System.out.println(ContentDll.INSTANCE.OpenDatabase(ip, name, username, password, tableName));
        System.out.println(videoDir);
        ContentDll.INSTANCE.ReleaseResultSet();
        System.out.println(ContentDll.INSTANCE.Search_Film(videoDir, CharacterJudger.isUTF_8()));
        int n = ContentDll.INSTANCE.GetResultCount();
        System.out.println(n);
        if (0 == n) {
            return null;
        }
        PageInfo pageInfo = new PageInfo(Long.parseLong(String.valueOf(n)), pageSize, page);
        VideoInfo videoInfo;
        List<SzTempVideo> list = new ArrayList<SzTempVideo>();
        if (page > pageInfo.getTotalPage()) {
            return null;
        }
        for (int i = Integer.parseInt(pageInfo.getBeginIndex().toString()); i < Integer.parseInt(pageInfo.getPageSize().toString()) + Integer.parseInt(pageInfo.getBeginIndex().toString()) && i < n
                ; i++) {
            System.out.println("i:" + i);
            videoInfo = ContentDll.INSTANCE.GetResultAt(i);
            if (null == videoInfo) {
                System.out.println(0);
            }
            /**
             * 生成视频片段
             */

            if (videoInfo.pcSeverName.equals(serverName)) {
                int random = new Random().nextInt();
                System.out.println(videoInfo.iFileID);
                String fileAndPath = videoInfo.pcFilePath;
                String videoTempDir = fileAndPath.substring(0, fileAndPath.lastIndexOf("\\"));
                videoTempDir = videoTempDir + "\\tempVideo";
                if (!new File(videoTempDir).exists()) {
                    new File(videoTempDir).mkdir();
                }
                videoTempDir = videoTempDir + "\\" + videoInfo.pcKeyFrameName;
                videoTempDir = videoTempDir.substring(0, videoTempDir.lastIndexOf("."));
                videoTempDir = videoTempDir + "-" + String.valueOf(random) + ".avs";
                Long blockSize = Long.parseLong(String.valueOf(videoInfo.iClipEndOffset - videoInfo.iClipStartOffset));
                Long beginPos = Long.parseLong(String.valueOf(videoInfo.iClipStartOffset));
                int headLength = videoInfo.iHeadLength;
                creatVideoFile.writeFile(fileAndPath,
                        videoTempDir,
                        blockSize,
                        beginPos, headLength);
                /**
                 * 构造SzTempVideo对象
                 */
                SzTempVideo tempVideo = new SzTempVideo();
                tempVideo.setSize(videoInfo.iFileSize);
                String minPictureUrl = videoInfo.pcKeyFrameFolder + videoInfo.pcKeyFrameName;
                minPictureUrl = minPictureUrl.substring(minPictureUrl.indexOf("video"));
                minPictureUrl = minPictureUrl.replace("\\", "/");
                tempVideo.setMinPictureUrl(minPictureUrl);
                tempVideo.setSzVideo(videoDAO.find(SzVideo.class, Long.parseLong(String.valueOf(videoInfo.iFileID))));
                tempVideo.setSzUser(null);
                tempVideo.setTempvideoId(Long.parseLong(String.valueOf(videoInfo.iFileID)));
                String tempVideoUrl = videoTempDir;
                tempVideoUrl = tempVideoUrl.substring(tempVideoUrl.indexOf("video"));
                tempVideoUrl = tempVideoUrl.replace("\\", "/");
                tempVideo.setVideoUrl(tempVideoUrl);
                SzVideo video = videoDAO.find(SzVideo.class, Long.parseLong(String.valueOf(videoInfo.iFileID)));
                tempVideo.setSzVideo(video);
                tempVideo.setTypeName(video.getSzVideoType().getName());
                //tempVideoDAO.saveOrUpdate(tempVideo);
                list.add(tempVideo);
            }

        }
        /*if (null != list) {
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                SzTempVideo temp = (SzTempVideo) iterator.next();
                temp.setMinPictureUrl(urlGetter.getRemoteUrl(temp.getMinPictureUrl(), temp.getSzVideo().getServer()));
            }
        }*/
        ContentDll.INSTANCE.ReleaseResultSet();
        System.out.println("list size:" + list.size());
        PageResultSet<SzTempVideo> pageResultSet = new PageResultSet<SzTempVideo>();
        pageResultSet.setPageInfo(pageInfo);
        pageResultSet.setList(list);
        return list;
    }

    @Override
    public Long findCount(String videoDir) {
        videoDir = applicationPath + videoDir;
        ContentDll.INSTANCE.OpenDatabase(ip, name, username, password, tableName);
        System.out.println(videoDir);
        System.out.println(ContentDll.INSTANCE.Search_Film(videoDir, CharacterJudger.isUTF_8()));
        int n = ContentDll.INSTANCE.GetResultCount();
        ContentDll.INSTANCE.ReleaseResultSet();
        return Long.parseLong(String.valueOf(n)); //TODO 待测
    }

    public void setVideoTypeDAO(VideoTypeDAO videoTypeDAO) {
        this.videoTypeDAO = videoTypeDAO;
    }

    public void setVideoDAO(VideoDAO videoDAO) {
        this.videoDAO = videoDAO;
    }

    public void setTempVideoDAO(TempVideoDAO tempVideoDAO) {
        this.tempVideoDAO = tempVideoDAO;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public void setApplicationPath(String applicationPath) {
        this.applicationPath = applicationPath;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    public void setUrlGetter(UrlGetter urlGetter) {
        this.urlGetter = urlGetter;
    }
}
